<template>
  <div class="excel-uploader">
    <!-- 模板下载 -->
    <el-alert
      type="info"
      :closable="false"
      style="margin-bottom: 20px"
    >
      <template #title>
        <div style="display: flex; align-items: center; justify-content: space-between">
          <span>请先下载标准模板，按照模板格式填写数据后上传</span>
          <el-button
            type="primary"
            size="small"
            :icon="Download"
            @click="downloadTemplate"
          >
            下载模板
          </el-button>
        </div>
      </template>
    </el-alert>

    <!-- 文件上传 -->
    <el-upload
      ref="uploadRef"
      class="upload-area"
      drag
      :action="uploadUrl"
      :headers="uploadHeaders"
      :data="{ type: uploadType }"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :show-file-list="false"
      accept=".xlsx,.xls"
    >
      <el-icon
        v-if="!uploading"
        class="upload-icon"
        :size="60"
      >
        <UploadFilled />
      </el-icon>
      <div
        v-if="!uploading"
        class="upload-text"
      >
        <p>将Excel文件拖到此处，或<em>点击上传</em></p>
        <p class="upload-tip">
          支持 .xlsx / .xls 格式，文件大小不超过10MB
        </p>
      </div>
      <div
        v-else
        class="uploading"
      >
        <el-progress
          type="circle"
          :percentage="uploadProgress"
        />
        <p>上传中...</p>
      </div>
    </el-upload>

    <!-- 上传结果 -->
    <div
      v-if="uploadResult"
      class="result-panel"
    >
      <el-result
        :icon="uploadResult.success > 0 ? 'success' : 'warning'"
        :title="`导入${uploadResult.success > 0 ? '成功' : '完成'}`"
      >
        <template #sub-title>
          <div class="result-stats">
            <div class="stat-item">
              <span class="label">总数:</span>
              <span class="value">{{ uploadResult.total }}</span>
            </div>
            <div class="stat-item success">
              <span class="label">成功:</span>
              <span class="value">{{ uploadResult.success }}</span>
            </div>
            <div class="stat-item failed">
              <span class="label">失败:</span>
              <span class="value">{{ uploadResult.failed }}</span>
            </div>
          </div>
        </template>
        <template #extra>
          <el-button
            type="primary"
            @click="resetUpload"
          >
            继续上传
          </el-button>
          <el-button
            v-if="uploadResult.errors && uploadResult.errors.length > 0"
            @click="showErrors"
          >
            查看错误详情
          </el-button>
        </template>
      </el-result>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * Excel上传组件
 *
 * Vue3 最佳实践:
 * 1. Props类型定义
 * 2. Emits事件类型定义
 * 3. 文件上传处理
 * 4. 进度展示
 */
import { ref, computed } from 'vue'
import notify from '@/utils/notify'
import { Download, UploadFilled } from '@element-plus/icons-vue'
import type { UploadInstance, UploadProgressEvent } from 'element-plus'

// ========== Props & Emits ==========
interface Props {
  uploadType: 'leads' | 'properties' | 'visitor-sheets' | 'performance'
  templateUrl: string
}

interface UploadResult {
  total: number
  success: number
  failed: number
  errors?: Array<{ row: number; error: string }>
}

const props = defineProps<Props>()
const emit = defineEmits<{
  success: [result: UploadResult]
}>()

// ========== 响应式数据 ==========
const uploadRef = ref<UploadInstance>()
const uploading = ref(false)
const uploadProgress = ref(0)
const uploadResult = ref<UploadResult | null>(null)

// ========== 计算属性 ==========
const uploadUrl = computed(() => {
  // ✅ 修复: 统一使用后端正确路径 /api/v1/imports/excel
  return '/api/v1/imports/excel'
})

const uploadHeaders = computed(() => {
  const token = localStorage.getItem('token')
  return {
    Authorization: `Bearer ${token}`,
  }
})

// ========== 方法 ==========

/**
 * 下载模板
 */
const downloadTemplate = () => {
  // 创建虚拟链接下载
  const link = document.createElement('a')
  link.href = props.templateUrl
  link.download = `${props.uploadType}_template.xlsx`
  link.click()

  notify.success('模板下载成功')
}

/**
 * 上传前校验
 */
const beforeUpload = (file: File) => {
  const isExcel =
    file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
    file.type === 'application/vnd.ms-excel'

  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isExcel) {
    notify.error('只能上传 Excel 文件!')
    return false
  }
  if (!isLt10M) {
    notify.error('文件大小不能超过 10MB!')
    return false
  }

  uploading.value = true
  uploadProgress.value = 0
  uploadResult.value = null

  return true
}

/**
 * 上传进度
 */
const handleProgress = (event: UploadProgressEvent) => {
  uploadProgress.value = Math.round(event.percent || 0)
}

/**
 * 上传成功
 */
const handleSuccess = (response: UploadResult) => {
  uploading.value = false
  uploadResult.value = response

  emit('success', response)

  if (response.failed === 0) {
    notify.success(`成功导入 ${response.success} 条数据`)
  } else {
    notify.warning(`成功 ${response.success} 条，失败 ${response.failed} 条`)
  }
}

/**
 * 上传失败
 */
const handleError = (error: Error) => {
  uploading.value = false
  console.error('Upload error:', error)
  notify.error('文件上传失败，请重试')
}

/**
 * 重置上传
 */
const resetUpload = () => {
  uploadResult.value = null
  uploadProgress.value = 0
}

/**
 * 显示错误详情
 */
const showErrors = () => {
  if (!uploadResult.value?.errors) return

  const errorHtml = uploadResult.value.errors
    .map((err: { row: number; error: string }) => `<p>第 ${err.row} 行: ${err.error}</p>`)
    .join('')

  notify.alertHtml(errorHtml, '错误详情')
}
</script>

<style scoped>
.excel-uploader {
  padding: 20px 0;
}

.upload-area {
  width: 100%;
}

:deep(.el-upload-dragger) {
  padding: 60px 0;
}

.upload-icon {
  color: #409eff;
  margin-bottom: 16px;
}

.upload-text p {
  margin: 8px 0;
  font-size: 16px;
  color: #606266;
}

.upload-text em {
  color: #409eff;
  font-style: normal;
}

.upload-tip {
  font-size: 12px !important;
  color: #999 !important;
}

.uploading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.result-panel {
  margin-top: 20px;
}

.result-stats {
  display: flex;
  gap: 24px;
  justify-content: center;
  margin-top: 16px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.stat-item .label {
  font-size: 14px;
  color: #666;
}

.stat-item .value {
  font-size: 24px;
  font-weight: bold;
  color: #333;
}

.stat-item.success .value {
  color: #52c41a;
}

.stat-item.failed .value {
  color: #f5222d;
}
</style>
